/*
 * @(#)NotificationAdapter.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.alert.core;

import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.mail.internet.AddressException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.alert.bean.MtmUpdateAlertRecipient;
import com.dcivision.alert.bean.UpdateAlert;
import com.dcivision.alert.bean.UpdateAlertSystemLog;
import com.dcivision.alert.bean.UpdateAlertType;
import com.dcivision.alert.dao.MtmUpdateAlertRecipientDAObject;
import com.dcivision.alert.dao.UpdateAlertDAObject;
import com.dcivision.alert.dao.UpdateAlertSystemLogDAObject;
import com.dcivision.alert.dao.UpdateAlertTypeDAObject;
import com.dcivision.calendar.bean.CalendarRecord;
import com.dcivision.calendar.dao.CalendarRecordDAObject;
import com.dcivision.dms.DmsOperationConstant;
import com.dcivision.dms.bean.DmsDefaultProfileSetting;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsDocumentDetail;
import com.dcivision.dms.core.DocumentRetrievalManager;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.MessageResourcesFactory;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.UserInfoFactory;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.GenericAddress;
import com.dcivision.framework.bean.SysUserDefinedIndex;
import com.dcivision.framework.bean.SysUserDefinedIndexDetail;
import com.dcivision.framework.notification.EmailDeliveryMessage;
import com.dcivision.framework.notification.NotificationWay;
import com.dcivision.framework.notification.NotificationWayFactory;
import com.dcivision.user.bean.UserDelegation;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserDelegationDAObject;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowStep;
import com.dcivision.workflow.dao.WorkflowProgressDAObject;
import com.dcivision.workflow.dao.WorkflowStepRouteDAObject;

/**
  StandardAdapter.java
  This class is the StandardAdapter.
    @author           Scott Tong
    @company          DCIVision Limited
    @creation date    22/08/2003
    @version          $Revision: 1.147.4.16 $
 */

public class NotificationAdapter implements StandardAdapter {

  public static final String REVISION = "$Revision: 1.147.4.16 $";
  private static final String NOTFIY_AT_FIELD_FOR_ZERO = "0";
  protected Log log = LogFactory.getLog(this.getClass().getName());
  private SessionContainer sessionContainer=null;
  private Connection conn=null;
  String sDear=null;
  String sMeetingInvitation=null;
  String sHostName=null;
  //String sMeetingTime=null;
  String sAwared=null;
  String sNotify=null;
  String sMessage=null;
  String sDuteDate=null;
  String sNotification=null;
  String sActorName=null;
  String sActionTaken=null;
  String sReferenceDoc=null;
  String sActionTime=null;
  String sWorkflow=null;
  String sTrackId=null;
  String sWorkflowStep=null;
  String sDescription=null;

  String sDetail=null;
  String sArrived=null;
  String sOverdue=null;
  String sStopped=null;
  String sBeforeDue=null;
  String sInProgressing=null;
  String sPendingFor=null;
  String sPriorityChange=null;
  String sYou=null;
  String sTask=null;
  String sFrom=null;
  String sTo=null;
  String sUntil=null;
  String sDelegated=null;
  String sComplete=null;
  String sPrirotyChanged = null;
  String sHere=null;
  String sTitle=null;
  String sVenue=null;
  String sCalendarDetail=null;
  String sCalendarFrom = null;
  String sReferenceNo=null;
  String sEffectiveDate=null;
  String sEffectiveSDate=null;
  String sEffectiveEDate=null;
  String sProfileName=null;
  String sCheckOutBy=null;
  String sCompletedBy=null;
  String attachmentName=null;
  byte[] attachmentByteAry=null;
  private HttpServletRequest request;

  public NotificationAdapter() {
    try {
      alertMessage(sessionContainer);
    } catch(Exception ex) {
      log.error(ex);
    }
  }

  public NotificationAdapter(SessionContainer sessionContainer, Connection conn) {
    try {
      alertMessage(sessionContainer);
    } catch(Exception ex) {
      log.error(ex);
    }
    this.sessionContainer = sessionContainer;
    this.conn = conn;
  }

  public void alertMessage(SessionContainer sessionContainer) throws Exception{

    /*java.util.Properties props = new java.util.Properties();
    Class cls = com.dcivision.alert.core.NotificationAdapter.class;
    java.security.ProtectionDomain pDomain = cls.getProtectionDomain();
    java.security.CodeSource cSource = pDomain.getCodeSource();
    java.net.URL loc = cSource.getLocation();
    String nPath=loc.toString();
    int n=nPath.indexOf("alert/core/NotificationAdapter.class");
    String path=nPath.substring(6,n);
    if (!path.endsWith("/")) {
          path += "/";
        }
        path += "resource/ApplicationResources.properties";
    java.io.FileInputStream fis = new java.io.FileInputStream(new java.io.File(path));
    props.load(fis);
    */
    sDear=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.dear");
    sMeetingInvitation=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.meeting_invitation");
    sHostName=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.host_name");
    //sMeetingTime=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.meeting_time");
    sAwared=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.awared");
    sNotify=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.notify");
    sMessage=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.message");
    sDuteDate=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.dute_date");
    sNotification=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.notification");
    sActorName=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.actor_name");
    sActionTaken=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.action_taken");
    sReferenceDoc=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.reference_doc");
    sActionTime=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.action_time");
    sWorkflow=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.workflow");
    sTrackId=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.track_id");
    sWorkflowStep=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.workflow_step");
    sDescription=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.description");
    sDetail=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.detail");
    sArrived=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.arrived");
    sOverdue=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.overdue");
    sStopped=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.stopped");
    sYou=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.you");
    sTask=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.task");
    sFrom=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.from");
    sTo=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.to");
    sUntil=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.until");
    sDelegated=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.delegated");
    sComplete=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.complete");
    sBeforeDue=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.beforedue");
    sInProgressing=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.inprogressing");
    sPrirotyChanged=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.prioritychange");
    sPendingFor=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.isPendingfor");
    sPriorityChange=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.prioritychange");
    sHere=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.here");
    sDelegated=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.delegated");
    sTitle=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.title");
    sVenue=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.venue");
    sCalendarDetail=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.calendar_detail");
    sCalendarFrom=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.calendar_from");
    sReferenceNo=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.reference_no");
    sEffectiveDate=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.effective_date");
    sEffectiveSDate=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.effective_start_date");;
    sEffectiveEDate=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.effective_end_date");;
    sProfileName=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.columnheader.profile_name");
    sCheckOutBy=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.checkoutBy");
    sCompletedBy=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.completedBy");
  }

  public void release() {
    this.sessionContainer = null;
    this.conn = null;
  }

  public void setNecessaryResource(SessionContainer sessionContainer,
                                   Connection conn) {
    this.sessionContainer = sessionContainer;
    this.conn = conn;
  }

  public void call(String objectType, Integer objectID, String eventType,
                   String objectName, Timestamp refDate, String eventName,
                   Integer creatorID) throws ApplicationException {
    this.call(objectType, objectID, eventType, objectName, refDate, eventName, creatorID, null);
  }

  public void call(String objectType, Integer objectID, String eventType,
                   String objectName, Timestamp refDate, String eventName,
                   Integer creatorID, Integer targetObjectID) throws ApplicationException {
    List alertList = new ArrayList();
    log.debug("File Type: " + objectType + " ID: " + objectID);
    log.debug("Event Type: " + eventType);
    AlertManager alertManager = new AlertManager(sessionContainer, conn);


    // Commented by Zoe; since we got 1 master update alert only, check to see whether the target doc got alert
    // alertList = alertManager.listUpdateAlertByObjectTypeObjectIDAndAction(objectType, objectID, eventType);
    //for (int i = 0; i < alertList.size(); i++) {
    UpdateAlert updateAlert = alertManager.getUpdateAlertByObjectTypeObjectID(objectType, objectID);
    UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
    PermissionManager permissionManager=new PermissionManager(sessionContainer);
    
    //if the objectID's document is havn't alert setting,then try to get this parent folder's alert setting
    if("D".equals(objectType)&&updateAlert==null){
      DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
      List parentList = docRetrievalManager.getAllParentDocumentList(objectID);
      if(!Utility.isEmpty(parentList)){
        for (int j = 0; j < parentList.size(); j++) {
          DmsDocument doc = (DmsDocument) parentList.get(j);
          if(!Utility.isEmpty(doc.getAlertEditID())){
            updateAlert = alertManager.getUpdateAlertByObjectTypeObjectID(objectType, doc.getID());
            break;
          }
        }
      }
    }
    boolean isDmsModule=false;
    if(UpdateAlert.DOCUMENT_TYPE.equals(objectType)
      ||UpdateAlert.AUTOMATE_CHECKIN.equals(objectType)
      ||UpdateAlert.EMAIL_ARCHIVE_TYPE.equals(objectType)) {
      isDmsModule=true;
    }
    if(isDmsModule){
      DmsDocumentDAObject dmsDocumentDAO=new DmsDocumentDAObject(sessionContainer,conn);
      DmsDocument tmp=(DmsDocument)dmsDocumentDAO.getObjectByID(objectID);
      if(tmp.isExpired()){return;}//Judgment document expired
    }

    if (updateAlert!=null) {
      List updateAlertTypeAry = updateAlertTypeDAO.getByUpdateAlertIDByOwnerID(updateAlert.getID(), eventType, null);
      /* Get the individual alert type by the alert owner and create the message */
      for (int j = 0; j < updateAlertTypeAry.size(); j++) {
        log.debug("updateAlertTypeAry.size() = " + updateAlertTypeAry.size());
        UpdateAlertType tmpUpdateAlertType = (UpdateAlertType)updateAlertTypeAry.get(j);
        StringTokenizer stoken = new StringTokenizer(tmpUpdateAlertType.getNotifyWay(), ",");
        log.debug("tmpUpdateAlertType.getID() = " + tmpUpdateAlertType.getID());
        List notifyChannelList = new ArrayList();

        /***/
        while (stoken.hasMoreElements()) {
          notifyChannelList.add(stoken.nextElement());
        }
        java.util.Collections.sort(notifyChannelList);
        Integer systemLogID = null;

        //      get current UserRecordID and UpdateAlertType CreterID
        Integer userRecordID = this.sessionContainer.getUserRecordID();
        Integer updateAlertTypeCreateID = tmpUpdateAlertType.getCreatorID();
        if (!GlobalConstant.TRUE.equals(tmpUpdateAlertType.getNotifySelf()) && userRecordID.intValue() == updateAlertTypeCreateID.intValue()) {
          continue;
        }
        
        if(isDmsModule){
          String setAlertRight=DmsOperationConstant.DMS_PERMISSION_ALLOW_SET_ALERT;
          boolean hasAlertRight=permissionManager.hasAccessRightByUserRecordId(updateAlertTypeCreateID,objectType,objectID,setAlertRight);
          if(!hasAlertRight){continue;}//Judgment set Alert right
        }

        for (int i=notifyChannelList.size();i>0;i--) {
          //String actionType = (String)stoken.nextElement();
          String actionType = (String)notifyChannelList.get(i-1);
          UpdateAlertSystemLog  updateAlertSystemLog = null;

          if (actionType.indexOf(UpdateAlert.SYSTEM_NOTIFICATION) >= 0) {
            if (targetObjectID!=null){
              updateAlertSystemLog = notifyBySystemMsg(eventType, updateAlert, tmpUpdateAlertType, targetObjectID);
            } else {
              updateAlertSystemLog = notifyBySystemMsg(eventType, updateAlert, tmpUpdateAlertType);
            }

            if (updateAlertSystemLog!=null) {
              systemLogID = updateAlertSystemLog.getID();
            }
          }

          if (actionType.indexOf(UpdateAlert.EMAIL_NOTIFICATION) >= 0) {
            if (UpdateAlert.INVITE_ACTION.equals(eventType)) {
              //notifyByEmailInvite(objectType, objectID, eventType, updateAlert,
              //                    objectName, refDate, eventName, creatorID);
            } else {
              if (targetObjectID!=null){
                notifyByEmail(eventType, tmpUpdateAlertType.getID(), objectID, objectName, objectType, targetObjectID, systemLogID);
              } else {
                notifyByEmail(eventType, tmpUpdateAlertType.getID(), objectID, objectName, objectType, systemLogID);
              }
            }
          }
        }
      }
    }
    updateAlertTypeDAO=null;
    alertManager.release();
//    }
  }

  protected void notifyByEmail(String eventType, Integer updateAlertTypeID, Integer objectID,
                                String objectName, String objectType) throws ApplicationException {
     this.notifyByEmail(eventType, updateAlertTypeID, objectID, objectName, objectType, null, null);
  }

  protected void notifyByEmail(String eventType, Integer updateAlertTypeID, Integer objectID,
                               String objectName, String objectType, Integer systemLogID) throws ApplicationException {
    this.notifyByEmail(eventType, updateAlertTypeID, objectID, objectName, objectType, null, systemLogID);
  }

  protected void notifyByEmail(String eventType, Integer updateAlertTypeID, Integer objectID,
                               String objectName, String objectType, Integer targetObjectID, Integer systemLogID) throws ApplicationException {

    log.debug("******** alert notification of email : " + eventType + " updateAlertTypeID : " + updateAlertTypeID);

    MtmUpdateAlertRecipientDAObject updateRecipientDAO = new MtmUpdateAlertRecipientDAObject(sessionContainer, conn);
    UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);

    List recipientAry = updateRecipientDAO.getByUpdateAlertTypeID(updateAlertTypeID);
    List userRoleIDs = new ArrayList();
    List userGroupIDs = new ArrayList();
    Set recipientUserRecordIDAry=new HashSet();
    UserRecordDAObject userRecordDAO = new UserRecordDAObject(sessionContainer,conn);

    for (int i = 0; i < recipientAry.size(); i++) {
      MtmUpdateAlertRecipient tmprecipient = (MtmUpdateAlertRecipient)recipientAry.get(i);
      //check recipient type
      if(GlobalConstant.SUBJECT_TYPE_USER.equals(tmprecipient.getRecipientType())){
        recipientUserRecordIDAry.add(tmprecipient.getRecipientID());
      }else if(GlobalConstant.SUBJECT_TYPE_ROLE.equals(tmprecipient.getRecipientType())){
        userRoleIDs.add(tmprecipient.getRecipientID());
      }else if(GlobalConstant.SUBJECT_TYPE_GROUP.equals(tmprecipient.getRecipientType())){
        userGroupIDs.add(tmprecipient.getRecipientID());
      }
    }
    recipientUserRecordIDAry.addAll(userRecordDAO.getIDListByLists(null, userGroupIDs, userRoleIDs));

    for(Iterator j=recipientUserRecordIDAry.iterator();j.hasNext();){
      Integer recipientID = (Integer)j.next();
      String targetUserEmailAddress = this.getUserEmailAddress(recipientID);
      //String userName = (String)UserInfoFactory.getUserFullName(recipientID);
      UpdateAlertType updateAlertType = (UpdateAlertType)updateAlertTypeDAO.getObjectByID(updateAlertTypeID);

      if (!Utility.isEmpty(targetUserEmailAddress)) {
        try {
          StringBuffer content = emailForDocumentAlertContent(objectType, objectID, eventType, updateAlertType, targetObjectID, systemLogID,recipientID);
          EmailDeliveryMessage msg = new EmailDeliveryMessage();
          msg.setSender(new GenericAddress(SystemParameterFactory.getSystemParameter(SystemParameterConstant.SMTP_ADMIN_ADDRESS),
                                            SystemParameterFactory.getSystemParameter(SystemParameterConstant.SMTP_ADMIN_NAME)));
          msg.addToRecipient(new GenericAddress(targetUserEmailAddress));
          msg.setSubject(SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_MAIL_ALERT_SUBJECT)+" [ "+objectName + " ] ");
          msg.setMailContent(content.toString());
          msg.setContentType(EmailDeliveryMessage.CONTENT_TYPE_HTML);
          NotificationWay emailNotification = NotificationWayFactory.getNotificationInstance(NotificationWay.EMAIL_NOTIFICATION_INSTANCE);
          emailNotification.addDeliveryMessage( msg);
          emailNotification.send();
        } catch (AddressException ae) {
          log.error(ae.getMessage(), ae);
          throw new ApplicationException(ae);
        } catch (UnsupportedEncodingException uee) {
          log.error(uee.getMessage(), uee);
          throw new ApplicationException(uee);
        }
      }
    }
    updateRecipientDAO=null;
    updateAlertTypeDAO=null;
  }

  protected void notifyByEmailInvite(String objectType, Integer objectID,
                                      String eventType, UpdateAlert updateAlert,
                                      String objectName, Timestamp refDate,
                                      String eventName, Integer creatorID,
                                      List notifyUserIDList) throws
     ApplicationException {
     this.notifyByEmailInvite(objectType, objectID, eventType, updateAlert, null,
                              objectName, refDate, eventName, creatorID, notifyUserIDList, null, null);
 }

  protected void notifyByEmailInvite(String objectType, Integer objectID,
                                     String eventType, UpdateAlert updateAlert,
                                     String objectName, Timestamp refDate,
                                     String eventName, Integer creatorID,
                                     List notifyUserIDList, Integer systemLogID) throws
    ApplicationException {
    this.notifyByEmailInvite(objectType, objectID, eventType, updateAlert, null,
                             objectName, refDate, eventName, creatorID, notifyUserIDList, null, systemLogID);
  }

  protected void notifyByEmailInvite(String objectType, Integer objectID,
                                      String eventType, UpdateAlert updateAlert,
                                      MtmUpdateAlertRecipient[] updateRecipient,
                                      String objectName, Timestamp refDate,
                                      String eventName, Integer creatorID,
                                      List notifyUserIDList) throws
     ApplicationException {
     this.notifyByEmailInvite(objectType, objectID, eventType, updateAlert, null,
                              updateRecipient, objectName, refDate, eventName, creatorID, notifyUserIDList, null, false, null, null);
   }
/**
 * @deprecated
 * @param objectType
 * @param objectID
 * @param eventType
 * @param updateAlert
 * @param updateRecipient
 * @param objectName
 * @param refDate
 * @param eventName
 * @param creatorID
 * @param notifyUserIDList
 * @param externalEmailList
 * @param systemLogID
 * @throws ApplicationException
 */
  protected void notifyByEmailInvite(String objectType, Integer objectID,
                                     String eventType, UpdateAlert updateAlert,
                                     MtmUpdateAlertRecipient[] updateRecipient,
                                     String objectName, Timestamp refDate,
                                     String eventName, Integer creatorID,
                                     List notifyUserIDList, List externalEmailList, Integer systemLogID) throws
    ApplicationException {
    this.notifyByEmailInvite(objectType, objectID, eventType, updateAlert, null,
                             updateRecipient, objectName, refDate, eventName, creatorID, notifyUserIDList, externalEmailList, false, systemLogID, null);
  }
  /**
   *
   *
   * @param updateAlert
   * @param updateRecipient
   * @param objectName
   * @param refDate
   * @param eventName
   * @param notifyUserIDList
   * @param externalEmailList
   * @param systemLogID
   * @param eventType
   * @param creatorID
   * @throws ApplicationException
   */
public void notifyByEmailInvite(UpdateAlert updateAlert, UpdateAlertType updateType,
      MtmUpdateAlertRecipient[] updateRecipient,
      String objectName, Timestamp refDate,
      String eventName, List notifyUserIDList, List externalEmailList, Integer systemLogID,String refObjID) throws
ApplicationException {
this.notifyByEmailInvite(updateAlert.getObjectType(), updateAlert.getObjectID(), updateType.getActionType(),
    updateAlert,updateType,updateRecipient, objectName, refDate, eventName,
    sessionContainer.getUserRecordID(),notifyUserIDList, externalEmailList, false, systemLogID, refObjID);
}
  protected void notifyByEmailInvite(String objectType, Integer objectID,
                                      String eventType, UpdateAlert updateAlert,
                                      MtmUpdateAlertRecipient[] updateRecipient,
                                      String objectName, Timestamp refDate,
                                      String eventName, Integer creatorID,
                                      List notifyUserIDList, boolean sendBySystem) throws

  ApplicationException {
    this.notifyByEmailInvite(objectType, objectID, eventType, updateAlert, null,
                               updateRecipient, objectName, refDate, eventName, creatorID, notifyUserIDList, null, sendBySystem, null, null);
  }

  private void notifyByEmailInvite(String objectType, Integer objectID,
                                     String eventType, UpdateAlert updateAlert,
                                     UpdateAlertType updateType,
                                     MtmUpdateAlertRecipient[] updateRecipient, String objectName,
                                     Timestamp refDate, String eventName,
                                     Integer creatorID, List notifyUserIDList, List externalEmailList, boolean sendBySystem, Integer systemLogID, String refObjID) throws
    ApplicationException {

    log.debug("******** notification of email invite system : " + eventType);
    for (int i = 0; i < notifyUserIDList.size(); i++) {
      Integer userID = (Integer)notifyUserIDList.get(i);
      String userName = UserInfoFactory.getUserFullName(userID);
      String userEmail = this.getUserEmailAddress(userID);
      log.debug("******** invite recipient user ID : " + userID + " email = " + userEmail);

      if (!Utility.isEmpty(userEmail)) {
        sendEmailforInvitation(objectType, objectID, eventType, updateAlert, updateType, objectName, refDate, eventName, creatorID, sendBySystem, systemLogID, userID, userName, userEmail, refObjID);
      }
    }
    if(!Utility.isEmpty(externalEmailList)){
      log.debug("******** notification of email invite system : " + eventType);
      for (int i = 0; i < externalEmailList.size(); i++) {
        String userEmail = (String)externalEmailList.get(i);

        if (!Utility.isEmpty(userEmail)) {
          sendEmailforInvitation(objectType, objectID, eventType, updateAlert, updateType, objectName, refDate, eventName, creatorID, sendBySystem, systemLogID, creatorID, userEmail, userEmail, refObjID);
        }
      }
    }
  }

  /**
   * @param objectType
   * @param objectID
   * @param eventType
   * @param updateAlert
   * @param updateType
   * @param objectName
   * @param refDate
   * @param eventName
   * @param creatorID
   * @param sendBySystem
   * @param systemLogID
   * @param userID
   * @param userName
   * @param userEmail
   * @param refObjID TODO
   * @throws ApplicationException
   */
  private void sendEmailforInvitation(String objectType, Integer objectID, String eventType, UpdateAlert updateAlert, UpdateAlertType updateType, String objectName, Timestamp refDate, String eventName, Integer creatorID, boolean sendBySystem, Integer systemLogID, Integer userID, String userName, String userEmail, String refObjID) throws ApplicationException {
    try {
      String contentType = getEmailContentType(eventType);
      StringBuffer content = getEmailContent(objectType, objectID, eventType, updateAlert, updateType, objectName, refDate, eventName, creatorID, systemLogID, userID, userName, refObjID);
      EmailDeliveryMessage msg = getFullEmailDeliveryMessage(objectType, eventType, objectName, creatorID, sendBySystem, userName, userEmail, contentType, content, objectID);
      if( !Utility.isEmpty(updateAlert) && !Utility.isEmpty(updateAlert.getAlertSubject())) {
        msg.setSubject(updateAlert.getAlertSubject());
      }
      NotificationWay emailNotification = NotificationWayFactory.getNotificationInstance(NotificationWay.EMAIL_NOTIFICATION_INSTANCE);
      emailNotification.addDeliveryMessage( msg);
      emailNotification.send();
    }
    catch (Exception uee) {
      //throw new ApplicationException("UnspportedEncodingException");
      log.debug(uee.toString());//don't to do nothing if sent email fail
    }
  }

  private EmailDeliveryMessage getFullEmailDeliveryMessage(String objectType, String eventType, String objectName, Integer creatorID, boolean sendBySystem, String userName, String userEmail, String contentType, StringBuffer content, Integer objectID) throws UnsupportedEncodingException, ApplicationException {
    // added by DICK
    // get step information by objectID ,
    // and add stepName to E_mail subject;
    WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
    WorkflowProgress workflowProgress = new WorkflowProgress();
    WorkflowStep workflowStep = new WorkflowStep();
    if (isWorkflowNotifyType(eventType)) {
      workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(objectID);
      workflowStep = workflowProgress.getWorkflowStepSource();
    }
    EmailDeliveryMessage msg = getEmailDeliveryMessage(creatorID, sendBySystem, userName, userEmail);
    if (UpdateAlert.CALENDAR_TYPE.equals(objectType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.CALENDAR_MAIL_SUBJECT));
    }
    else if (UpdateAlert.NOTIFY_TASK_COMPLETED_ACTION.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_COMPLETED_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }
    else if (UpdateAlert.NOTIFY_TASK_ARRIVED_ACTION.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_ARRIVED_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }
    else if (UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_OVERDUE_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }
    else if (UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_OVERDUE_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }
    else if (UpdateAlert.NOTIFY_STOP_TRACK.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_TRACK_STOP_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }
    else if (UpdateAlert.NOTIFY_TASK_PENDING_FOR.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_PENDING_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
    else if (UpdateAlert.NOTIFY_TASK_IN_PROGRESSING.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_INPROGRESSING_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
    else if (UpdateAlert.NOTIFY_BEFORE_DUE_DATE.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_BEFOREDUE_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
    else if (UpdateAlert.DELEGATION_ACTION.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_DELEGATION_NOTIFICATION_SUBJECT));
    }
    else if (UpdateAlert.NOTIFY_DELEGATION_USER.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
          SystemParameterConstant.WORKFLOW_DELEGATION_USER_NOTIFICATION_SUBJECT));
    }
    else if (UpdateAlert.INVITE_ACTION.equals(eventType)) {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.DMS_MAIL_INVITE_SUBJECT)+" [ "+objectName + " ] ");
    }else if (UpdateAlert.DOCUMENT_INVITATION_EXPIRED.equals(eventType)) {
      msg.setSubject(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),
          "email.subject.notification_document_invitation_expiry", objectName));
    }else if (UpdateAlert.DOCUMENT_INVITATION_UPDATE_DUEDATE.equals(eventType)) {
      msg.setSubject(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),
          "email.subject.notification_document_invitation_update_due_date", objectName));
    }else if (UpdateAlert.DOCUMENT_INVITATION_CANCEL.equals(eventType)) {
      msg.setSubject(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),
          "email.subject.notification_document_invitation_cancel", objectName));
    }else if(UpdateAlert.DISCUSS_ACTION.equals(eventType)){
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.DMS_MAIL_INVITE_SUBJECT)+" [ "+objectName + " ] ");
    }
    else if(UpdateAlert.NOTIFY_TASK_PRIORITY_CHANGED.equals(eventType)){
        msg.setSubject(SystemParameterFactory.getSystemParameter(
          SystemParameterConstant.WORKFLOW_MAIL_PRIORITY_CHANGED_NOTIFICATION_SUBJECT)+ " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
    else if(UpdateAlert.NOTIFY_TASK_CHECK_OUT_BY_USER.equals(eventType)){
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_CHECK_OUT_BY_USER_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }
    else if(UpdateAlert.NOTIFY_TASK_COMPLETED_BY_USER.equals(eventType)){
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.WORKFLOW_MAIL_COMPLETED_BY_USER_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
    }


    else if(UpdateAlert.NOTIFY_TASK_APPROVED.equals(eventType)){
        msg.setSubject(SystemParameterFactory.getSystemParameter(
          SystemParameterConstant.WORKFLOW_MAIL_APPROVED_BY_USER_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
      else if(UpdateAlert.NOTIFY_TASK_REJECT.equals(eventType)){
        msg.setSubject(SystemParameterFactory.getSystemParameter(
          SystemParameterConstant.WORKFLOW_MAIL_REJECTED_BY_USER_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
      else if(UpdateAlert.NOTIFY_TASK_YES.equals(eventType)){
        msg.setSubject(SystemParameterFactory.getSystemParameter(
          SystemParameterConstant.WORKFLOW_MAIL_SELECTED_YES_BY_USER_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
      else if(UpdateAlert.NOTIFY_TASK_NO.equals(eventType)){
        msg.setSubject(SystemParameterFactory.getSystemParameter(
          SystemParameterConstant.WORKFLOW_MAIL_SELECTED_NO_BY_USER_NOTIFICATION_SUBJECT) + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
      }
      else if ((!Utility.isEmpty(eventType)) && (eventType.indexOf(UpdateAlert.NOTIFY_TASK_DECISION) == 0)) {
          String subject = SystemParameterFactory.getSystemParameter(SystemParameterConstant.WORKFLOW_MAIL_SELECTED_DECISION_BY_USER_NOTIFICATION_SUBJECT);
          String routeName = "";
          WorkflowStepRouteDAObject routeDAO = new WorkflowStepRouteDAObject(sessionContainer, conn);
          String sub = eventType.substring(1);
          int id = Integer.parseInt(sub);
          routeName = routeDAO.getRouteNameByStepIDAndSeq(workflowStep.getID(), id);
          MessageFormat mf = new MessageFormat(subject);
          subject=mf.format(new Object[]{routeName});
          msg.setSubject(subject + " [" + workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "]");
        }

    else {
      msg.setSubject(SystemParameterFactory.getSystemParameter(
        SystemParameterConstant.DMS_MAIL_ALERT_SUBJECT)+" [ "+objectName+" ] ");
    }
    msg.setMailContent(content.toString());
    msg.setContentType(contentType);
    //if exist attachment ,add it
    if(attachmentName!=null){
      msg.addAttachment(attachmentName, attachmentByteAry);
    }
    return msg;
  }

  private boolean isWorkflowNotifyType(String eventType) {
    boolean isWorkflowNotifyType = UpdateAlert.NOTIFY_BEFORE_DUE_DATE.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(eventType) ||
    UpdateAlert.NOTIFY_STOP_TRACK.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_ARRIVED_ACTION.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_CHECK_OUT_BY_USER.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_COMPLETED_ACTION.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_COMPLETED_BY_USER.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_IN_PROGRESSING.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_PENDING_FOR.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_PRIORITY_CHANGED.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_APPROVED.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_REJECT.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_YES.equals(eventType) ||
    UpdateAlert.NOTIFY_TASK_NO.equals(eventType) ||
    (!Utility.isEmpty(eventType)) &&  (eventType.indexOf(UpdateAlert.NOTIFY_TASK_DECISION)==0);
    return isWorkflowNotifyType;
  }

  private String getEmailContentType(String eventType) {
    String contentType   = EmailDeliveryMessage.CONTENT_TYPE_PLAIN;
    if (UpdateAlert.INVITE_ACTION.equals(eventType)) {
      contentType   = EmailDeliveryMessage.CONTENT_TYPE_HTML;
    }
    return contentType;
  }

  private EmailDeliveryMessage getEmailDeliveryMessage(Integer creatorID, boolean sendBySystem, String userName, String userEmail) throws UnsupportedEncodingException {
    EmailDeliveryMessage msg = new EmailDeliveryMessage();

    if (!sendBySystem) {
      String emailAddress = null;
      try{
        emailAddress = getUserEmailAddress(creatorID);
      }catch(ApplicationException ex){log.info(ex);}
      msg.setSender(new GenericAddress(emailAddress,
                                        UserInfoFactory.getUserFullName(creatorID), "UTF-8"));
    }
    else {
      msg.setSender(new GenericAddress(SystemParameterFactory.getSystemParameter(SystemParameterConstant.SMTP_ADMIN_ADDRESS),
                                        SystemParameterFactory.getSystemParameter(SystemParameterConstant.SMTP_ADMIN_NAME), "UTF-8"));
    }
    msg.addToRecipient(new GenericAddress(userEmail, userName, "UTF-8"));
    return msg;
  }

  private StringBuffer getEmailContent(String objectType, Integer objectID, String eventType, UpdateAlert updateAlert, UpdateAlertType updateType, String objectName, Timestamp refDate, String eventName, Integer creatorID, Integer systemLogID, Integer userID, String userName, String refObjID) throws ApplicationException {
    StringBuffer content = new StringBuffer();
    //default text/plain
    if (UpdateAlert.INVITE_ACTION.equals(eventType)) {
      if (UpdateAlert.DOCUMENT_TYPE.equals(objectType)) {
        content = emailForDocumentInviteContent(objectName, objectID, eventType, userName, userID, updateAlert, updateType, eventName, systemLogID);
      }
      else if (UpdateAlert.CALENDAR_TYPE.equals(objectType)) {
        content = emailForCalendarInviteContent(objectName, objectID,eventType, userName, refDate, eventName, creatorID);
      }
    }
    else {
      if(UpdateAlert.DOCUMENT_INVITATION_EXPIRED.equals(eventType)
          ||UpdateAlert.DOCUMENT_INVITATION_CANCEL.equals(eventType)
          ||UpdateAlert.DOCUMENT_INVITATION_UPDATE_DUEDATE.equals(eventType)){
      String sentDate = "N/A";
      String dueDate = "N/A";
      if(!Utility.isEmpty(updateType)){
        UpdateAlertTypeDAObject updateTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
        UpdateAlertType updateAlertType = (UpdateAlertType) updateTypeDAO.getObjectByID(TextUtility.parseIntegerObj(refObjID));
        try {
          sentDate =   new SimpleDateFormat("yyyy-MM-dd",sessionContainer.getSessionLocale()).format(updateAlertType.getCreateDate());
        }
        catch (Exception e) {
          sentDate = "N/A";
          log.error(e, e);
        }
        try {
          if(!Utility.isEmpty(updateType.getDueDate())){
          dueDate =   new SimpleDateFormat("yyyy-MM-dd",sessionContainer.getSessionLocale()).format(updateType.getDueDate());
          }
         }
        catch (Exception e) {
          dueDate = "N/A";
          log.error(e, e);
        }
      }
      if(UpdateAlert.DOCUMENT_INVITATION_EXPIRED.equals(eventType)){
          content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),
              "email.content.notification_document_invitation_expiry",objectName,
              sentDate));
      }
      else if (UpdateAlert.DOCUMENT_INVITATION_CANCEL.equals(eventType)) {
        content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),
            "email.content.notification_document_invitation_cancel",objectName,
            sentDate));
      }
      else if (UpdateAlert.DOCUMENT_INVITATION_UPDATE_DUEDATE.equals(eventType)) {
        content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),
            "email.content.notification_document_invitation_update_due_date",objectName,
            dueDate));
      }
      }else if(UpdateAlert.DISCUSS_ACTION.equals(eventType)){
        if (UpdateAlert.DOCUMENT_TYPE.equals(objectType)) {
          content = emailForDocumentInviteContent(objectName, objectID, eventType, userName, userID, updateAlert, null, eventName, systemLogID);
        }
      }
      else if (UpdateAlert.NOTIFY_TASK_COMPLETED_ACTION.equals(eventType)) {
        content = emailForWorkflowNotifyTaskCompletedContent(userName, userID, objectID);
      }
      else if (UpdateAlert.NOTIFY_TASK_COMPLETED_BY_USER.equals(eventType)) {
        content = emailForWorkflowNotifyTaskCompletedByUser(userName, userID, objectID, creatorID);
      }
      else if (UpdateAlert.NOTIFY_TASK_ARRIVED_ACTION.equals(eventType)) {
        content = emailForWorkflowNotifyTaskArrivedContent(userName, userID, objectID);
      }
      else if (UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(eventType)) {
        content = emailForWorkflowNotifyTaskOwnerOverdueContent(userName, objectID);
      }
      else if (UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(eventType)) {
        content = emailForWorkflowNotifyTaskAllOverdueContent(userName, objectID);
      }
      else if (UpdateAlert.NOTIFY_STOP_TRACK.equals(eventType)) {
        content = emailForWorkflowNotifyTrackStop(userName, objectID);
      }
      else if (UpdateAlert.NOTIFY_BEFORE_DUE_DATE.equals(eventType)) {
        content = emailForWorkflowNotifyTaskBeforeDueContent(userName, objectID, objectName, eventName);
      }
      else if (UpdateAlert.NOTIFY_TASK_IN_PROGRESSING.equals(eventType)) {
        content = emailForWorkflowNotifyTaskInProgressingContent(userName, userID, objectID, objectName, eventName);
      }
      else if(UpdateAlert.NOTIFY_TASK_PRIORITY_CHANGED.equals(eventType)){
        content = emailForWorkflowNotifyTaskPrirotyChanged(userName, userID, objectID);
      }
      else if (UpdateAlert.NOTIFY_TASK_CHECK_OUT_BY_USER.equals(eventType)) {
        content = emailForWorkflowNotifyTaskCheckOutByUser(userName, userID, objectID, objectName, eventName, creatorID);
      }
      else if (UpdateAlert.NOTIFY_TASK_PENDING_FOR.equals(eventType)) {
        content = emailForWorkflowNotifyTaskPendingForContent(userName, userID, objectID, objectName, eventName);
      }
      else if (UpdateAlert.DELEGATION_ACTION.equals(eventType)) {
        content = emailForDelegationContent(userName, objectID);
      }
      else if (UpdateAlert.NOTIFY_DELEGATION_USER.equals(eventType)) {
        content = emailForNotifyDelegationUserContent(userName, objectID);
      }
      else{

              content=emailForWorkflowNotifyTaskBranchCompletedByUser(userName, userID, objectID, creatorID,eventType);


log.warn("**** No suitable email content ****");
      }
    }
    return content;
  }
  private StringBuffer emailForWorkflowNotifyTaskBranchCompletedByUser(String userName, Integer userID, Integer workflowProgressID, Integer actionID, String eventType) {
      StringBuffer content = new StringBuffer();
      String alertMessage = "alert.message.completedBy";
      String routeName ="";

      boolean isDection=(!Utility.isEmpty(eventType)) &&  (eventType.indexOf(UpdateAlert.NOTIFY_TASK_DECISION)==0);

      if (UpdateAlert.NOTIFY_TASK_APPROVED.equals(eventType)) {
        alertMessage = "alert.message.selected_approved";
      } else if (UpdateAlert.NOTIFY_TASK_REJECT.equals(eventType)) {
        alertMessage = "alert.message.selected_reject";
      } else if (UpdateAlert.NOTIFY_TASK_YES.equals(eventType)) {
        alertMessage = "alert.message.selected_yes";
      } else if (UpdateAlert.NOTIFY_TASK_NO.equals(eventType)) {
        alertMessage = "alert.message.selected_no";
      } else if (isDection) {
        alertMessage = "alert.message.selected_decition";
      }

      try {
        WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
        WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
        WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();
        if (isDection) {
          WorkflowStepRouteDAObject routeDAO = new WorkflowStepRouteDAObject(sessionContainer, conn);
          String sub = eventType.substring(1);
          int id = Integer.parseInt(sub);
           routeName = routeDAO.getRouteNameByStepIDAndSeq(workflowStep.getID(), id);
        }
        content.append(sDear + " "+userName + ",\n\n");

        // if current step is
        if (isDection) {
          content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),alertMessage, routeName,UserInfoFactory.getUserFullName(actionID))).append("\n");
        } else {
          content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),alertMessage, UserInfoFactory.getUserFullName(actionID))).append("\n");
        }
        content.append("<table><tr><td>");
        content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        if (workflowStep.getOnNoResponseAfter() != null) {
          content.append(sDuteDate).append("</td><td>:</td><td>").append(
                         TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                                SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                              + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
        }
        else if (workflowStep.getOnNoResponseFor() != null) {
          long tmp = workflowProgress.getCreateDate().getTime();
          tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
          Timestamp dueDate = new Timestamp(tmp);
          content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                            getWeekdayByDate(dueDate)  +"\n");
        }
        StringBuffer onClickURL = new StringBuffer();
        try {
          onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
          onClickURL.append("&userID=").append(userID);
          //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_dle
          onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
        } catch (java.io.UnsupportedEncodingException e) {
          new ApplicationException(e);
        }
        content.append("</td></tr></table>");
        content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
        progressDAO=null;
      } catch (Exception e) {
        log.error(e, e);
      }

      return content;
    }

  //protected void notifyBySystemMsg(String eventType, UpdateAlert updateAlert, UpdateAlertType updateAlertType) throws
  protected UpdateAlertSystemLog notifyBySystemMsg(String eventType, UpdateAlert updateAlert, UpdateAlertType updateAlertType) throws
    ApplicationException {
    return this.notifyBySystemMsg(eventType, updateAlert, updateAlertType, null);
  }

  //protected void notifyBySystemMsg(String eventType, UpdateAlert updateAlert, UpdateAlertType updateAlertType, Integer targetObjectID) throws
  protected  UpdateAlertSystemLog notifyBySystemMsg(String eventType, UpdateAlert updateAlert, UpdateAlertType updateAlertType, Integer targetObjectID) throws
    ApplicationException {

    Integer userID = sessionContainer.getUserRecordID();
    //String userName = (String) UserInfoFactory.getUserFullName(userID);
    //String userEmail = (String) UserInfoFactory.getUserEmailAddress(userID);

    log.debug("******** notification of system : " + eventType + " action user ID : " + userID);

    UpdateAlertSystemLog alertSystemLog = new UpdateAlertSystemLog();
    alertSystemLog.setActionUserID(userID);
    alertSystemLog.setRefObjectID(targetObjectID);
//    UpdateAlertTypeDAObject alertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
//    UpdateAlertType alertType = (UpdateAlertType)alertTypeDAO.getIDByTypeUpdateAlertID(eventType, updateAlert.getID());
    alertSystemLog.setUpdateAlertTypeID(updateAlertType.getID());
    alertSystemLog.setRecordStatus(GlobalConstant.STATUS_ACTIVE);

    UpdateAlertSystemLogDAObject alertSystemLogDAO = new UpdateAlertSystemLogDAObject(sessionContainer, conn);
    alertSystemLog = (UpdateAlertSystemLog)alertSystemLogDAO.insertObject(alertSystemLog);
    alertSystemLogDAO=null;

    return alertSystemLog;
  }

  protected void notifyBySystemMsgOnInvite(String eventType, UpdateAlert updateAlert) throws ApplicationException {

    Integer userID = sessionContainer.getUserRecordID();
    //String userName = (String) UserInfoFactory.getUserFullName(userID);
    //String userEmail = (String) UserInfoFactory.getUserEmailAddress(userID);

    log.debug("******** notification of system : " + eventType + " action user ID : " + userID);

    UpdateAlertSystemLog alertSystemLog = new UpdateAlertSystemLog();
    alertSystemLog.setActionUserID(userID);

    UpdateAlertTypeDAObject alertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
    UpdateAlertType alertType = (UpdateAlertType)alertTypeDAO.getIDByTypeUpdateAlertID(eventType, updateAlert.getID());
    alertSystemLog.setUpdateAlertTypeID(alertType.getID());
    alertSystemLog.setRecordStatus(GlobalConstant.STATUS_ACTIVE);

    UpdateAlertSystemLogDAObject alertSystemLogDAO = new UpdateAlertSystemLogDAObject(sessionContainer, conn);
    alertSystemLog = (UpdateAlertSystemLog)alertSystemLogDAO.insertObject(alertSystemLog);

    alertTypeDAO=null;
    alertSystemLogDAO=null;
  }

  public StringBuffer emailForCalendarInviteContent(String objectName,Integer objectID, String eventType, String userName, Timestamp refDate, String eventName, Integer creatorID){
    StringBuffer content = new StringBuffer();
    String actionDate = "";

    try{
        CalendarRecordDAObject calendarRecordDAObject = new CalendarRecordDAObject(sessionContainer, conn);
        CalendarRecord calendarRecord = (CalendarRecord)calendarRecordDAObject.getObjectByID(objectID);

        actionDate = TextUtility.formatTimestamp(refDate);
        //eventName = calendarRecord.getTitle();
        String appBaseURL = getApplicationBaseURL();
        //String onClickURL = appBaseURL + "/jsp/dms/FileDownload.jsp?sCurFunctionCode=" + sCurFunctionCode + "&targetID=" + dmsDocument.getID() + "&version=" + DmsOperationConstant.DMS_TOP_VERSION;
        String onClickURL=appBaseURL + "/calendar/MaintCalendar.do?navMode=V&isHome=true&isHome=true&isHome=true&opReply=True&ID="+calendarRecord.getID();
//        try {
//          onClickURL = appBaseURL + "/Login.do?action=redirect&url="+java.net.URLEncoder.encode(onClickURL, "UTF-8");
//        } catch (java.io.UnsupportedEncodingException e) {
//          throw new ApplicationException(e);
//        }
        String hostName = UserInfoFactory.getUserFullName(creatorID);
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm a",java.util.Locale.ENGLISH);
        if(calendarRecord != null){
          /*
            content.append(sDear +" "+ userName + ",\n\n");
          content.append(sAwared + "\n\n");

          content.append(sTitle + ":\t");
          content.append("<a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + calendarRecord.getTitle() + "</a>\n");

          content.append(sCalendarFrom + ":\t");
          content.append(dateFormat.format(calendarRecord.getDatetime())+"\n");

          content.append(sTo + ":\t");
          content.append(dateFormat.format(calendarRecord.getEndtime())+"\n");

          content.append(sVenue + ":\t");
          content.append(calendarRecord.getVenue()+"\n");

          content.append(sCalendarDetail + ":\t");
          content.append(calendarRecord.getVenue()+"\n");
          */

          content.append(sDear + " " +userName + ",\n\n");
          content.append(sAwared + "\n");
          content.append("<p valign=\"top\">");
          content.append("<table border=\"0\">");

          content.append("<tr>");
          content.append("  <td>" + sTitle + ":</td>");
          content.append("  <td><a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + calendarRecord.getTitle() + "</a></td>");
          content.append("</tr>");

          //Update By Jim.Zhou			2006/07/19			Bug	5919
          if (!"Y".equals(calendarRecord.getIsWholeDay())) {
            content.append("<tr>");
            content.append("  <td>" + sCalendarFrom + ":</td>");
            content.append("  <td>" + dateFormat.format(calendarRecord.getDatetime()) + "</td>");
            content.append("</tr>");

            content.append("<tr>");
            content.append("  <td>" + sTo + ":</td>");
            content.append("  <td>" + dateFormat.format(calendarRecord.getEndtime()) + "</td>");
            content.append("</tr>");
          } else {
            content.append("<tr>");
            content.append("  <td>" + sCalendarFrom + "/" + sTo + ":</td>");
            content.append("  <td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.label.is_whole_day_event") + "</td>");
            content.append("</tr>");
          }
          //Update End

          content.append("<tr>");
          content.append("  <td>" + sVenue + ":</td>");
          content.append("  <td>" + calendarRecord.getVenue() + "</td>");
          content.append("</tr>");

          content.append("<tr>");
          content.append(" <td>" + sHostName + ":</td>");
          content.append(" <td>" + hostName + "</td>");
          content.append("</tr>");

          content.append("<tr>");
          content.append("  <td>" + sCalendarDetail + ":</td>");
          content.append("  <td>" + calendarRecord.getDetail() + "</td>");
          content.append("</tr>");
          content.append("</table>");
          content.append("</p>");
          //EIP-3393 Rollback Calendar .ics export
          //attachmentName = calendarRecord.getTitle()+".ics";
          //attachmentByteAry = calendarRecord.toByteAry();
        }
    }catch(Exception e) {
      log.error(e);
    }
    return content;
  }

  public StringBuffer emailForCalendarInviteContent(Integer objectID, String userName, Timestamp refDate, Integer creatorID, String type){
    StringBuffer content = new StringBuffer();
    String actionDate = "";
    String modified = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.mail.modified");
    String deleted = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.mail.deleted");

    try{
        CalendarRecordDAObject calendarRecordDAObject = new CalendarRecordDAObject(sessionContainer, conn);
        CalendarRecord calendarRecord = (CalendarRecord)calendarRecordDAObject.getObjectByID(objectID);

        actionDate = TextUtility.formatTimestamp(refDate);
        //eventName = calendarRecord.getTitle();
        String appBaseURL = getApplicationBaseURL();
        //String onClickURL = appBaseURL + "/jsp/dms/FileDownload.jsp?sCurFunctionCode=" + sCurFunctionCode + "&targetID=" + dmsDocument.getID() + "&version=" + DmsOperationConstant.DMS_TOP_VERSION;
        String onClickURL=appBaseURL + "/calendar/MaintCalendar.do?navMode=V&isHome=true&isHome=true&isHome=true&opReply=True&ID="+calendarRecord.getID();
        try {
          onClickURL = appBaseURL + "/Login.do?action=redirect&url="+java.net.URLEncoder.encode(onClickURL, "UTF-8");
        } catch (java.io.UnsupportedEncodingException e) {
          throw new ApplicationException(e);
        }
        String hostName = UserInfoFactory.getUserFullName(creatorID);
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm a",java.util.Locale.ENGLISH);
        if(calendarRecord != null){
          content.append(sDear + " " +userName + ",\n\n");
          if("U".equals(type)){
            content.append(modified+"\n");
          }else if("D".equals(type)){
            content.append(deleted+"\n");
          }
          content.append("<p valign=\"top\">");
          content.append("<table border=\"0\">");
          content.append("<tr>");
          content.append("  <td>" + sTitle + ":</td>");
          if("D".equals(type)){
            content.append("  <td>" + calendarRecord.getTitle() + "</a></td>");
          }else if("U".equals(type)){
            content.append("  <td><a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + calendarRecord.getTitle() + "</a></td>");
          }

          content.append("</tr>");

          //Update By Jim.Zhou			2006/07/19			Bug	5919
          if (!"Y".equals(calendarRecord.getIsWholeDay())) {
            content.append("<tr>");
            content.append("  <td>" + sCalendarFrom + ":</td>");
            content.append("  <td>" + dateFormat.format(calendarRecord.getDatetime()) + "</td>");
            content.append("</tr>");

            content.append("<tr>");
            content.append("  <td>" + sTo + ":</td>");
            content.append("  <td>" + dateFormat.format(calendarRecord.getEndtime()) + "</td>");
            content.append("</tr>");
          } else {
            content.append("<tr>");
            content.append("  <td>" + sCalendarFrom + "/" + sTo + ":</td>");
            content.append("  <td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.label.is_whole_day_event") + "</td>");
            content.append("</tr>");
          }
          //Update End

          content.append("<tr>");
          content.append("  <td>" + sVenue + ":</td>");
          content.append("  <td>" + calendarRecord.getVenue() + "</td>");
          content.append("</tr>");

          content.append("<tr>");
          content.append(" <td>" + sHostName + ":</td>");
          content.append(" <td>" + hostName + "</td>");
          content.append("</tr>");

          content.append("<tr>");
          content.append("  <td>" + sCalendarDetail + ":</td>");
          content.append("  <td>" + calendarRecord.getDetail() + "</td>");
          content.append("</tr>");
          content.append("</table>");
          content.append("</p>");
        }
    }catch(Exception e) {
    }
    return content;
  }


  public StringBuffer emailForDocumentInviteContent(String objectName, Integer objectID, String eventType, String userName, Integer userID, UpdateAlert updateAlert, UpdateAlertType updateType, String eventName, Integer systemLogID) throws ApplicationException{
    StringBuffer content = new StringBuffer();
    String dueDate = "";
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    DmsDocumentDAObject dmsDocmentDAO = new DmsDocumentDAObject(sessionContainer, conn);

    Timestamp dueDateTime = null;
    String message = "";

    if(!Utility.isEmpty(updateType)){
     dueDateTime = updateType.getDueDate();
     message = updateType.getMessage();
    }
      //AlertManager alertManager = new AlertManager(sessionContainer, conn);
//    UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
//
//    List alertTypeList = updateAlertTypeDAO.getByUpdateAlertIDByOwnerID(updateAlert.getID(), eventType, sessionContainer.getUserRecordID());
//
//    UpdateAlertType alertType = new UpdateAlertType(); //alertManager.getUpdateAlertTypeByActionTypeUpdateAlertID(UpdateAlert.INVITE_ACTION, updateAlert.getID());
//    String fieldValue="";
//    if (!Utility.isEmpty(alertTypeList)) {
//      if(UpdateAlert.DISCUSS_ACTION.equals(eventType)){
//        alertType = (UpdateAlertType) alertTypeList.get(alertTypeList.size()-1);
//      }else{
//        alertType = (UpdateAlertType) alertTypeList.get(0);
//      }
//
      dueDate = TextUtility.formatTimestampToDate(dueDateTime);
//    }
    DmsDocument dmsDocument = docRetrievalManager.getDocument(objectID);
    
    if (dmsDocument!=null) {

      String location = docRetrievalManager.getLocationPath(dmsDocument.getParentID());
      String sCurFunctionCode = docRetrievalManager.getCurFunctionCode(dmsDocument);
      String appBaseURL = getApplicationBaseURL();
//      //String onClickURL = "'"+ appBaseURL + "/jsp/dms/FileDownload.jsp?sCurFunctionCode=" + sCurFunctionCode + "&targetID=" + dmsDocument.getID() + "&version=" + DmsOperationConstant.DMS_TOP_VERSION + "'";
//      String onClickURL=appBaseURL + "/dms/MaintDmsDocument.do?documentType=" + dmsDocument.getDocumentType() + "&rootID=" + dmsDocument.getRootID() + "&parentID="
//      + dmsDocument.getID() + "&sCurFunctionCode=" + sCurFunctionCode + "&navMode=" + GlobalConstant.NAV_MODE_PREVIEW + "&ID=" + dmsDocument.getID() + "&objectID=" + dmsDocument.getID()+"&fromEmail=true";
//      //onClickURL=onClickURL+"&updateAlertType="+updateAlert.getAlertType()+"&updateAlertID="+updateAlert.getID();
//
//      //onClickURL = onClickURL + "&updateAlertID="+updateAlert.getID()+"&actionType="+alertType.getActionType();
//      if(systemLogID!=null){
//          onClickURL = onClickURL + "&updateAlertSystemLogID="+systemLogID+"&updateReadOperation="+"true";
//      }
//  old
//      String onClickURL=appBaseURL + "/dms/ViewInvitation.do?updateAlertID="+updateAlert.getID();
      String onClickURL =appBaseURL + "/EditMessageDetail.do?messageType=documentInvitation&objectid="
                    +updateAlert.getObjectID().toString()+ "&updateAlertTypeID="+ updateType.getID().toString()
                    + "&isList=no&isFromEmail=yes";
//      String onClickURL=appBaseURL +
//      "/dms/maintDmsInvitationAction.do?actionType=S&opMode=P&documentID="+updateAlert.getObjectID()
//      +"&updateAlertID="+updateAlert.getID();
      String referenceNo = TextUtility.noNull(dmsDocument.getReferenceNo());
      String description = TextUtility.noNull(dmsDocument.getDescription());
      Timestamp effectiveDate = dmsDocument.getEffectiveStartDate();
//      SysUserDefinedIndex udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(dmsDocument);
//      SysUserDefinedIndexDetail udfDetail=null;
//      try {
//        onClickURL = appBaseURL + "/Login.do?action=redirect&userID="+userID+"&url="+java.net.URLEncoder.encode(onClickURL, "UTF-8");
//      } catch (java.io.UnsupportedEncodingException e) {
//        throw new ApplicationException(e);
//      }

      //String hostName = (String) UserInfoFactory.getUserFullName(updateAlert.getCreatorID());
      String hostName = UserInfoFactory.getUserFullName(sessionContainer.getUserRecordID());

      boolean isShowPersonalOwner = ((location.indexOf(DmsDocument.PERSONAL_ROOT_FOLDER_NAME) != -1) && (userID.intValue() != sessionContainer.getUserRecordID().intValue()));
      if(isShowPersonalOwner) {
        location = hostName + "'s " + location;
      }
      
      content.append("<p valign=\"top\">");
      content.append(sDear + " " +userName + ",<br><br>");
      //content.append(sDear + " "+ userName + ",\n\n");

      if(UpdateAlert.DISCUSS_ACTION.equals(eventType)){
        sNotify=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.notify_discuss",hostName);
      }else{
        sNotify=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.notify",hostName);
      }
      content.append(sNotify + "<br><br>");

      content.append("<table border=\"0\">");

      content.append("<tr>");
      content.append("  <td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.location")+"</td>");
      content.append("  <td> : </td>");
      content.append("  <td>" + location + "</td>");
      content.append("</tr>");

      content.append("<tr>");
      content.append("  <td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_" + dmsDocument.getDocumentType()) + "</td>");
      content.append("  <td> : </td>");
      content.append("  <td><a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + objectName + "</a></td>");
      content.append("</tr>");
      
      content.append("<tr>");
      content.append("  <td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.document.url") + "</td>");
      content.append("  <td> : </td>");
      content.append("  <td><a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + onClickURL + "</a></td>");
      content.append("</tr>");

      content.append("<tr>");
      content.append(" <td>" + sReferenceNo + "</td>");
      content.append(" <td> : </td>");
      content.append(" <td>" + referenceNo  + "</td>");
      content.append("</tr>");

      content.append("<tr>");
      content.append(" <td>" + sDescription + "</td>");
      content.append(" <td> : </td>");
      content.append(" <td>" + description  + "</td>");
      content.append("</tr>");


      // Retrieve the default document profile settings.
      List dmsDefaultProfile = null;
      String[] dudf = {dmsDocument.getUserDef1(),dmsDocument.getUserDef2(),dmsDocument.getUserDef3(),dmsDocument.getUserDef4(),
          dmsDocument.getUserDef5(),dmsDocument.getUserDef6(),dmsDocument.getUserDef7(),dmsDocument.getUserDef8(),
          dmsDocument.getUserDef9(),dmsDocument.getUserDef10()};

      int totalFieldCount = Integer.parseInt(com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.
          DMS_DEFAULT_PROFILE_FIELD_COUNT));
      com.dcivision.dms.dao.DmsDefaultProfileSettingDAObject dmsProfileDAO = new com.dcivision.dms.dao.DmsDefaultProfileSettingDAObject(null, conn);
    dmsDefaultProfile = dmsProfileDAO.getFullList();
    for (int i = 0; i < totalFieldCount; i++) {
      DmsDefaultProfileSetting setting = (DmsDefaultProfileSetting) dmsDefaultProfile.get(i);
        content.append("<tr>");
        content.append(" <td>" + setting.getFieldName() + "</td>");
        content.append(" <td> : </td>");
        if(dudf[i]==null|| "null".equals(dudf[i])){
            content.append(" <td>" +  ""  + "</td>");
        }else{
            content.append(" <td>" +  (dudf[i] == null?"":dudf[i])  + "</td>");
        }
        content.append("</tr>");
      }

      // Show document profile(s) information.
    List result = new ArrayList();
      result = dmsDocmentDAO.getDocumentProfileInfo(dmsDocument,"");
      for (int i = 1; i<result.size(); i++) {
        String[] saInfo = (String[])result.get(i);
        String sCurrent = ((String[])result.get(i))[0];
        String sPrevious = ((String[])result.get(i-1))[0];
        if (!(sCurrent.equals(sPrevious))){
          content.append("<tr>");
          content.append(" <td >" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.profile_name") + "</td>"); // dms.label.profile_name
          content.append(" <td> : </td>");
          content.append(" <td >"+ TextUtility.escapeJSString(TextUtility.plainTextToHtml(saInfo[0])) + "</td>");
          content.append("</tr>");
        }
        if (!Utility.isEmpty(saInfo[0]) && !Utility.isEmpty(saInfo[1])){
          content.append("<tr>");
          content.append(" <td >"+ TextUtility.escapeJSString(TextUtility.plainTextToHtml(saInfo[1])) + " </td>");
          content.append(" <td> : </td>");
          content.append(" <td >"+ TextUtility.escapeJSString(TextUtility.plainTextToHtml(saInfo[2])) + "</td>");
          content.append("</tr>");
        }
      }

      content.append("<tr>");
      content.append(" <td>" + sEffectiveDate + "</td>");
      content.append(" <td> : </td>");
      content.append(" <td>" + TextUtility.formatDate(effectiveDate,SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) + "</td>");
      content.append("</tr>");

      content.append("<tr>");
      content.append(" <td>" + sMessage + "</td>");
      content.append(" <td> : </td>");
      content.append(" <td>" + (Utility.isEmpty(message)?"":message)+ "</td>");
      content.append("</tr>");
/*
      content.append("<tr>");
      content.append(" <td>" + sHostName + "</td>");
      content.append(" <td> : </td>");
      content.append(" <td>" + hostName + "</td>");
      content.append("</tr>");
*/
      if(!Utility.isEmpty(dueDate)){
        content.append("<tr>");
        content.append(" <td>" + sDuteDate + "</td>");
        content.append(" <td> : </td>");
        content.append(" <td>" +  dueDate+" "+ getWeekdayByDate(dueDateTime) + "</td>");
        content.append("</tr>");
      }

      content.append("</p>");
    }

    docRetrievalManager.release();
    return content;
  }

  public StringBuffer emailForDocumentAlertContent(String objectType, Integer objectID, String eventType, UpdateAlertType updateAlertType, Integer targetObjectID, Integer systemLogID) throws ApplicationException {
    return emailForDocumentAlertContent(objectType, objectID, eventType, updateAlertType, targetObjectID, systemLogID,null);
  }

  public StringBuffer emailForDocumentAlertContent(String objectType, Integer objectID, String eventType, UpdateAlertType updateAlertType, Integer targetObjectID, Integer systemLogID,Integer recipientUserRecordID) throws ApplicationException {
    StringBuffer content = new StringBuffer();
    //String userName = (String)UserInfoFactory.getUserFullName(updateAlertType.getCreatorID());
    //if send email to group, the alert type creator is not equal to recipients
    String userName = null;
    if(recipientUserRecordID==null){
      userName = UserInfoFactory.getUserFullName(updateAlertType.getCreatorID());
    }else{
      userName = UserInfoFactory.getUserFullName(recipientUserRecordID);
    }
    String actorName = UserInfoFactory.getUserFullName(sessionContainer.getUserRecordID());
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    DmsDocument dmsDocument = docRetrievalManager.getDocument(objectID);
    DmsDocument parDocument = docRetrievalManager.getDocument(dmsDocument.getParentID());
    DmsDocument targetDocument = null;
    String targetDocURL = "";
//    String referenceNo = TextUtility.noNull(dmsDocument.getReferenceNo());
//    String description = TextUtility.noNull(dmsDocument.getDescription());
//    Timestamp effectiveDate = dmsDocument.getEffectiveStartDate();
//    SysUserDefinedIndex udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(dmsDocument);
    String referenceNo = "";
    String description = "";
    String[] defaultProfiles = null;
    Timestamp effectiveSDate = null;
    Timestamp effectiveEDate   = null;
    SysUserDefinedIndex udfIndex = null;


    SysUserDefinedIndexDetail udfDetail=null;
    String fieldValue="";


    if (dmsDocument!=null) {
      String objectName = dmsDocument.getDocumentName();
      String location = docRetrievalManager.getLocationPath(dmsDocument.getParentID());
      String sCurFunctionCode = docRetrievalManager.getCurFunctionCode(dmsDocument);
      String appBaseURL = getApplicationBaseURL();
      //String onClickURL = "'"+appBaseURL + "/jsp/dms/FileDownload.jsp?sCurFunctionCode=" + sCurFunctionCode + "&targetID=" + dmsDocument.getID() + "&version=" + DmsOperationConstant.DMS_TOP_VERSION+"'";
      String onClickURL = "";
      String folderName = "";
      String folderOnClickURL = "";
      if(!(Utility.isEmpty(parDocument))){
        folderName = parDocument.getDocumentName();
        folderOnClickURL = appBaseURL +"/dms/ListDmsPublicDocument.do?rootID="+parDocument.getRootID()+"&parentID="+parDocument.getID();
      }

        /*
        * If targetObjectID is not null, it should be a folder alert, and the document/folder under triggered the alert
        */
        if (targetObjectID!=null) {
          targetDocument = docRetrievalManager.getDocument(targetObjectID);

          referenceNo = TextUtility.noNull(targetDocument.getReferenceNo());
          description = TextUtility.noNull(targetDocument.getDescription());
          defaultProfiles = this.getUserDefaultProfiles(targetDocument);
          effectiveSDate = targetDocument.getEffectiveStartDate();
          effectiveEDate = targetDocument.getEffectiveEndDate();
          udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(targetDocument);

          targetDocURL = appBaseURL + "/EditMessageDetail.do?messageType=documentNotification&objectid="
          +targetObjectID.toString()+ "&updateAlertTypeID="+ updateAlertType.getID().toString()
          + "&isList=no&isFromEmail=yes";
        } else {
        referenceNo = TextUtility.noNull(dmsDocument.getReferenceNo());
        description = TextUtility.noNull(dmsDocument.getDescription());
        defaultProfiles = this.getUserDefaultProfiles(dmsDocument);
        effectiveSDate = dmsDocument.getEffectiveStartDate();
        effectiveEDate = dmsDocument.getEffectiveEndDate();
        udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(dmsDocument);
        }

        /*
        * The object that triggered the alert can either be document or folder
        */
        if (DmsDocument.DOCUMENT_TYPE.equals(dmsDocument.getDocumentType())||DmsDocument.COMPOUND_DOC_TYPE.equals(dmsDocument.getDocumentType())) {
        onClickURL = appBaseURL + "/EditMessageDetail.do?messageType=documentNotification&objectid="
            +objectID.toString()+ "&updateAlertTypeID="+ updateAlertType.getID().toString()+ "&isList=no&isFromEmail=yes";
        }else if (DmsDocument.FOLDER_TYPE.equals(dmsDocument.getDocumentType())) {
            if (SystemFunctionConstant.DMS_PERSONAL_FOLDER.equals(sCurFunctionCode)){
                //For Personal Folder
                onClickURL = appBaseURL + "/dms/ListDmsDocument.do?rootID=" + dmsDocument.getRootID() + "&parentID=" + dmsDocument.getID();
            } else {
                //For Public Folder
                onClickURL = appBaseURL + "/dms/ListDmsPublicDocument.do?rootID=" + dmsDocument.getRootID() + "&parentID=" + dmsDocument.getID();
      }
        }

      String sNdear=this.sDear;
      String actionType = "";
      String actionTypeMsg = "";
      if (UpdateAlert.CREATE_ACTION.equals(eventType)) {
        actionType    = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.notification_create"); //"has created a ";
        actionTypeMsg = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "alert.message.created");
      } else if (UpdateAlert.DELETE_ACTION.equals(eventType)) { //For Delete Action
        actionType    = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.notification_delete"); //"has deleted a ";
        actionTypeMsg = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "alert.message.deleted");
      } else if (UpdateAlert.UPDATE_ACTION.equals(eventType)) { //For Update Action
        actionType    = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.notification_update"); //"has updated a ";
        actionTypeMsg = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "alert.message.updated");
      } else if (UpdateAlert.VIEW_ACTION.equals(eventType)) { //For View Action
        actionType    = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.notification_view"); //"has viewed a ";
        actionTypeMsg = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "alert.message.viewed");
      } else if (UpdateAlert.MODIFY_RELATED_DOC.equals(eventType)){
        actionType    = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.document_relationship");
        actionTypeMsg = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "alert.message.setup_relationship");
      }else if(UpdateAlert.MOVE_ACTION.equals(eventType)){
        actionType    = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.notification_move");//"has moved a ";
        actionTypeMsg = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "alert.message.moved");
      }

      content.append(sNdear + " " +userName + ",\n\n");
      content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.notification",actionTypeMsg)+"\n\n");
      content.append("<p valign=\"top\">");
      content.append("<table border=\"0\">");

      // TODO: Need to handle if the document/folder is deleted, should not let users click the hyperlink
      content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.location") + "</td><td>:</td><td>" + location + "</td></tr>");
      
      if(GlobalConstant.NAV_MODE_DELETE.equals(eventType)){
        if(!(Utility.isEmpty(folderName))){
          content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_Z" ) + "</td><td>:</td><td>"); 
          content.append(folderName + "</td></tr>");
        }
        content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_" + dmsDocument.getDocumentType()) + "</td><td>:</td><td>");
        content.append(objectName + "</td></tr>");
      } else {
        if(onClickURL.indexOf("/dms/ListDmsDocument.do") == -1) {
          if(!(Utility.isEmpty(folderName))){
            content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_Z" ) + "</td><td>:</td><td>"); 
            content.append("<a href='" + folderOnClickURL + "' target='DCIVisionAppWindow'>" + folderName + "</a></td></tr>");
            
            content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.folder.url" ) + "</td><td>:</td><td>"); 
            content.append("<a href='" + folderOnClickURL + "' target='DCIVisionAppWindow'>" + folderOnClickURL + "</a></td></tr>");
          }
          content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_" + dmsDocument.getDocumentType()) + "</td><td>:</td><td>");
          content.append("<a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + objectName + "</a></td></tr>");
          
          content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.document.url") + "</td><td>:</td><td>");
          content.append("<a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + onClickURL + "</a></td></tr>");
        } else {
          //if it is the Personal Folder, remove the hyperlink. change for #EIP-2166 by wiflish.xie 
          if(!(Utility.isEmpty(folderName))){
            content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_Z" ) + "</td><td>:</td><td>"); 
            content.append(folderName + "</td></tr>");
          }
          
          content.append("<tr><td>" + MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_" + dmsDocument.getDocumentType()) + "</td><td>:</td><td>");
          content.append(objectName + "</td></tr>");
        }
      }

      if (!Utility.isEmpty(targetDocument)) {
        if(GlobalConstant.NAV_MODE_DELETE.equals(eventType)){
          content.append("<tr><td>" + sReferenceDoc +  "</td><td>:</td><td>" + targetDocument.getDocumentName() + "</td></tr>");
        }else{
        content.append("<tr><td>" + sReferenceDoc +  "</td><td>:</td><td><a href='" + targetDocURL + "' target='DCIVisionAppWindow'>" + targetDocument.getDocumentName() + "</a></td></tr>");
      }
      }
      content.append("<tr><td>" + sReferenceNo +"</td><td>:</td><td>"+referenceNo + "</td></tr>");
      content.append("<tr><td>" + sDescription +"</td><td>:</td><td>"+description + "</td></tr>");
      for (int i=0; !Utility.isEmpty(defaultProfiles) && i<defaultProfiles.length; i++) {
        content.append("<tr><td>Field " +(i+1) +"</td><td>:</td><td>"+ TextUtility.noNull(defaultProfiles[i])+ "</td></tr>");
      }
      if (udfIndex!=null) {
        content.append("<tr><td>" + sProfileName+"</td><td>:</td><td>"+udfIndex.getUserDefinedType()+"</td></tr>");
        List udfDetailList = docRetrievalManager.getUDFDetailList(udfIndex.getID());
        for (int k=0; k<udfDetailList.size(); k++) {
          udfDetail = (SysUserDefinedIndexDetail)udfDetailList.get(k);
          DmsDocumentDetail dmsDocumentDetail = null;
          if (!Utility.isEmpty(targetObjectID)){
              dmsDocumentDetail = docRetrievalManager.getDetailObjectByDocIDUDFDetailID(targetObjectID, udfDetail.getID());
          }else{
              dmsDocumentDetail = docRetrievalManager.getDetailObjectByDocIDUDFDetailID(objectID, udfDetail.getID());
          }
          if (dmsDocumentDetail!=null){
            if (udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.DATE_FIELD) ){
              fieldValue = dmsDocumentDetail.getDateValue()==null ? "" : dmsDocumentDetail.getDateValue().toString();
            } else if (udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.STRING_FIELD) ||
                       udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.FIELD_TYPE_SELECT_DATABASE)){
              fieldValue = dmsDocumentDetail.getFieldValue()==null ? "" : dmsDocumentDetail.getFieldValue().toString();
            } else if (udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.NUMBER_FIELD) ){
              fieldValue = dmsDocumentDetail.getNumericValue()==null? "" : dmsDocumentDetail.getNumericValue().toString();
            }
          }
          content.append("<tr><td>" + udfDetail.getFieldName()+"</td><td>:</td><td>"+fieldValue+"</td></tr>");
        }

      }
      if (!DmsDocument.FOLDER_TYPE.equals(dmsDocument.getDocumentType())) {
        // Folder lifecycle is disabled in EIP-1773
      content.append("<tr><td>" + sEffectiveSDate +"</td><td>:</td><td>"+TextUtility.formatDate(effectiveSDate,SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))+"</td></tr>");
      content.append("<tr><td>" + sEffectiveEDate +"</td><td>:</td><td>"+TextUtility.formatDate(effectiveEDate,SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))+"</td></tr>");
     }
      content.append("<tr><td>" + sActorName +"</td><td>:</td><td>"+ actorName + "</td></tr>");
      content.append("<tr><td>" + sActionTaken + "</td><td>:</td><td>"+actionType + "</td></tr>");
      /* It should not be the updateAlertType.getCreateDate()
      content.append("<tr><td>" + sActionTime +"</td><td>:</td><td>"+TextUtility.formatTimestamp(updateAlertType.getCreateDate())
            + " "+getWeekdayByDate(updateAlertType.getCreateDate()) + "</td></tr>");
      */

      // TOFIX: Why is it using now? Should it be using the document/folder's update time?
      Timestamp now = new Timestamp(System.currentTimeMillis());
      content.append("<tr><td>" + sActionTime + "</td><td>:</td><td>" + TextUtility.formatTimestamp(now) + " "+getWeekdayByDate(now) + "</td></tr>");
      content.append("</table>");
      content.append("</p>");
    }
    docRetrievalManager.release();
    return content;
  }

  public StringBuffer emailForWorkflowNotifyTaskCompletedContent(String userName, Integer userID, Integer workflowProgressID) {
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(sComplete).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                          getWeekdayByDate(dueDate)  +"\n");
      }
      StringBuffer onClickURL = new StringBuffer();
      try {
        onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
        onClickURL.append("&userID=").append(userID);
        //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
        onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
      } catch (java.io.UnsupportedEncodingException e) {
        new ApplicationException(e);
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public StringBuffer emailForWorkflowNotifyTaskCompletedByUser(String userName, Integer userID, Integer workflowProgressID, Integer actionID) {
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.completedBy", UserInfoFactory.getUserFullName(actionID))).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                          getWeekdayByDate(dueDate)  +"\n");
      }
      StringBuffer onClickURL = new StringBuffer();
      try {
        onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
        onClickURL.append("&userID=").append(userID);
        //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
        onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
      } catch (java.io.UnsupportedEncodingException e) {
        new ApplicationException(e);
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }


  public StringBuffer emailForWorkflowNotifyTaskPrirotyChanged(String userName, Integer userID, Integer workflowProgressID) {
      StringBuffer content = new StringBuffer();

      try {
        WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
        WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
        WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

        content.append(sDear + " "+userName + ",\n\n");
        content.append(sPrirotyChanged).append("\n");
        content.append("<table border=0><tr><td>");
        content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        if (workflowStep.getOnNoResponseAfter() != null) {
          content.append(sDuteDate).append("</td><td>:</td><td>").append(
                         TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                                SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                              + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
        }
        else if (workflowStep.getOnNoResponseFor() != null) {
          long tmp = workflowProgress.getCreateDate().getTime();
          tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
          Timestamp dueDate = new Timestamp(tmp);
          content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                            getWeekdayByDate(dueDate)  +"\n");
        }
        StringBuffer onClickURL = new StringBuffer();
        try {
          onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
          onClickURL.append("&userID=").append(userID);
          //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
          onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
        } catch (java.io.UnsupportedEncodingException e) {
          new ApplicationException(e);
        }
        content.append("</td></tr></table>");
        content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
        progressDAO=null;
      } catch (Exception e) {
        log.error(e, e);
      }

      return content;
    }


  //public StringBuffer emailForWorkflowNotifyTaskArrivedContent(String userName, Integer userID, Integer workflowProgressID){//simon_del
  public StringBuffer emailForWorkflowNotifyTaskArrivedContent(String userName, Integer userID, Integer workflowProgressID) throws ApplicationException{//simon_add
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(sArrived).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())   + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  +"\n");
      }
      StringBuffer onClickURL = new StringBuffer();
      try {
        onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
        onClickURL.append("&userID=").append(userID);
        //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
        onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
      } catch (java.io.UnsupportedEncodingException e) {
        new ApplicationException(e);
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
      progressDAO=null;
    } catch (ApplicationException appEx) {//simon_add
      throw appEx;//simon_add
    } catch (Exception e) {
      log.error(e, e);
    }
    return content;
  }

  public StringBuffer emailForWorkflowNotifyTaskInProgressingContent(String userName, Integer userID, Integer workflowProgressID, String notifyAtAmt, String notifyAtFiled) {
    StringBuffer content = new StringBuffer();
    String notifyAtFiledStr = null;
    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();
      if (Calendar.DATE == Integer.parseInt(notifyAtFiled)) {
        notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.days");
      } else if (Calendar.HOUR == Integer.parseInt(notifyAtFiled)){
        notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.hours");
      } else {
        notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.minutes");
      }
      content.append(sDear + " "+userName + ",\n\n");
      //content.append(sInProgressing);
      //if (!(NOTFIY_AT_FIELD_FOR_ZERO.equals(notifyAtAmt))) {
      //  content.append(" [" + notifyAtAmt +" ] " + notifyAtFiledStr);
      //}
      //content.append("\n\n");

      content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.inprogressing", (notifyAtAmt +" " + notifyAtFiledStr) )).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())   + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  +"\n");
      }
      StringBuffer onClickURL = new StringBuffer();
      try {
        onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
        onClickURL.append("&userID=").append(userID);
        //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
        onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
      } catch (java.io.UnsupportedEncodingException e) {
        new ApplicationException(e);
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public StringBuffer emailForWorkflowNotifyTaskCheckOutByUser(String userName, Integer userID, Integer workflowProgressID, String notifyAtAmt, String notifyAtFiled, Integer actionID) {
    StringBuffer content = new StringBuffer();
    String notifyAtFiledStr = null;
    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();
      if (Calendar.DATE == Integer.parseInt(notifyAtFiled)) {
        notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.days");
      } else if (Calendar.HOUR == Integer.parseInt(notifyAtFiled)){
        notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.hours");
      } else {
        notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.minutes");
      }
      content.append(sDear + " "+userName + ",\n\n");
      content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.checkoutBy", (notifyAtAmt +" " + notifyAtFiledStr), UserInfoFactory.getUserFullName(actionID))).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())   + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  +"\n");
      }
      StringBuffer onClickURL = new StringBuffer();
      try {
        onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
        onClickURL.append("&userID=").append(userID);
        //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
        onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
      } catch (java.io.UnsupportedEncodingException e) {
        new ApplicationException(e);
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }


  public StringBuffer emailForWorkflowNotifyTaskPendingForContent(String userName, Integer userID, Integer workflowProgressID, String notifyAtAmt, String notifyAtFiled) {
    StringBuffer content = new StringBuffer();
    String notifyAtFiledStr = null;
    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
        WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();
        if (Calendar.DATE == Integer.parseInt(notifyAtFiled)) {
          notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.days");
        } else if (Calendar.HOUR == Integer.parseInt(notifyAtFiled)){
          notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.hours");
        } else {
          notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.minutes");
        }
        content.append(sDear + " "+userName + ",\n\n");
        //content.append(sPendingFor);
        //if (!(NOTFIY_AT_FIELD_FOR_ZERO.equals(notifyAtAmt))) {
        //  content.append(" [" + notifyAtAmt +" ] " + notifyAtFiledStr);
        //}
        //content.append("\n\n");

        content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.isPendingfor", (notifyAtAmt +" " + notifyAtFiledStr))).append("\n");
        content.append("<table border=0><tr><td>");
        content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
        content.append("</td></tr>");
        content.append("<tr><td>");
        if (workflowStep.getOnNoResponseAfter() != null) {
          content.append(sDuteDate).append("</td><td>:</td><td>").append(
                         TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                                SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                              + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())   + "\n");
        }
        else if (workflowStep.getOnNoResponseFor() != null) {
          long tmp = workflowProgress.getCreateDate().getTime();
          tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
          Timestamp dueDate = new Timestamp(tmp);
          content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                          getWeekdayByDate(dueDate)  +"\n");
        }
        StringBuffer onClickURL = new StringBuffer();
        try {
          onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
          onClickURL.append("&userID=").append(userID);
          //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
          onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
        } catch (java.io.UnsupportedEncodingException e) {
          new ApplicationException(e);
        }
        content.append("</td></tr></table>");
        content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
        progressDAO=null;
      } catch (Exception e) {
        log.error(e, e);
      }

      return content;
    }

  public StringBuffer emailForWorkflowNotifyTaskPriorityChangeContent(String userName, Integer userID, Integer workflowProgressID) {
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(sPriorityChange).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                               SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())   + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  +"\n");
      }
      StringBuffer onClickURL = new StringBuffer();
      try {
        onClickURL.append(getApplicationBaseURL()).append("/Login.do?action=redirect");
        onClickURL.append("&userID=").append(userID);
        //onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/ListWorkflowTask.do", "UTF-8"));//simon_del
        onClickURL.append("&url=").append(java.net.URLEncoder.encode(getApplicationBaseURL()+"/workflow/MaintWorkflowTask.do?navMode=E&delegateUserRecordID=null&trackID="+workflowProgress.getTrackID()+"&ID="+workflowProgress.getID()+"&workflowRecordID="+workflowProgress.getWorkflowRecordID()+"&workflowStepID="+workflowProgress.getWorkflowStepID(), "UTF-8"));//simon_add
      } catch (java.io.UnsupportedEncodingException e) {
        new ApplicationException(e);
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='" +onClickURL.toString()+"'>"+sHere+"</a>\n");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }



  public StringBuffer emailForWorkflowNotifyTaskOwnerOverdueContent(String userName, Integer workflowProgressID) {
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(sOverdue).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            +" "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  + "\n");
      }
      content.append("</td></tr></table>");
      content.append(sDetail +":&nbsp; <a href='"+TextUtility.formatRedirectLoginString("workflow/ListWorkflowTask.do")+"'>"+sHere+"</a>");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public StringBuffer emailForWorkflowNotifyTaskAllOverdueContent(String userName, Integer workflowProgressID) {
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(sOverdue).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  + "\n");
      }
      content.append("</td></tr></table>");
      content.append(sDetail +":&nbsp; <a href='"+TextUtility.formatRedirectLoginString("workflow/ListWorkflowTask.do")+"'>"+sHere+"</a>");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public StringBuffer emailForWorkflowNotifyTaskBeforeDueContent(String userName, Integer workflowProgressID, String notifyAtAmt, String notifyAtFiled) {
     StringBuffer content = new StringBuffer();
     String notifyAtFiledStr = null;

     try {
       WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
       WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
       WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();
       if (Calendar.DATE == Integer.parseInt(notifyAtFiled)) {
         notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.days");
       } else if (Calendar.HOUR == Integer.parseInt(notifyAtFiled)){
         notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.hours");
       } else {
         notifyAtFiledStr = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "workflow.label.minutes");
       }
       content.append(sDear + " "+userName + ",\n\n");
       //content.append(sBeforeDue);
       //if (!(NOTFIY_AT_FIELD_FOR_ZERO.equals(notifyAtAmt))) {
       //  content.append(" [" + notifyAtAmt +" ] " + notifyAtFiledStr);
       //}
       //content.append("\n\n");

       content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.beforedue",(notifyAtAmt +" " + notifyAtFiledStr) )).append("\n");
       content.append("<table border=0><tr><td>");
       content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
       content.append("</td></tr>");
       content.append("<tr><td>");
       content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
       content.append("</td></tr>");
       content.append("<tr><td>");
       content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
       content.append("</td></tr>");
       content.append("<tr><td>");
       if (workflowStep.getOnNoResponseAfter() != null) {
         content.append(sDuteDate).append("</td><td>:</td><td>").append(
                        TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                               SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                             + " "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
       }
       else if (workflowStep.getOnNoResponseFor() != null) {
         long tmp = workflowProgress.getCreateDate().getTime();
         tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
         Timestamp dueDate = new Timestamp(tmp);
         content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                         getWeekdayByDate(dueDate)  + "\n");
       }
       content.append("</td></tr></table>");
       content.append(sDetail +":&nbsp; <a href='"+TextUtility.formatRedirectLoginString("workflow/ListWorkflowTask.do")+"'>"+sHere+"</a>");
       progressDAO=null;
     } catch (Exception e) {
       log.error(e, e);
     }

     return content;
   }

  public StringBuffer emailForWorkflowNotifyTrackStop(String userName, Integer workflowProgressID) {
    StringBuffer content = new StringBuffer();

    try {
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgress workflowProgress = (WorkflowProgress)progressDAO.getObjectByID(workflowProgressID);
      WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();

      content.append(sDear + " "+userName + ",\n\n");
      content.append(sStopped).append("\n");
      content.append("<table border=0><tr><td>");
      content.append(sTrackId).append("</td><td>:</td><td>").append(TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(), workflowProgress.getTrackID()) + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sWorkflowStep).append("</td><td>:</td><td>").append(workflowStep.getStepSeq() + ". " + workflowStep.getStepName() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sDescription).append("</td><td>:</td><td>").append(workflowStep.getDescription() + "\n");
      content.append("</td></tr>");
      content.append("<tr><td>");
      if (workflowStep.getOnNoResponseAfter() != null) {
        content.append(sDuteDate).append("</td><td>:</td><td>").append(
                       TextUtility.formatDate(workflowStep.getOnNoResponseAfter(),
                                              SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))
                                                                                            +" "+getWeekdayByDate(workflowStep.getOnNoResponseAfter())  + "\n");
      }
      else if (workflowStep.getOnNoResponseFor() != null) {
        long tmp = workflowProgress.getCreateDate().getTime();
        tmp += workflowStep.getOnNoResponseFor().intValue() * 24 * 60 * 60 * 1000;
        Timestamp dueDate = new Timestamp(tmp);
        content.append(sDuteDate).append("</td><td>:</td><td>").append(TextUtility.formatDate(dueDate, SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT)) +" "+
                        getWeekdayByDate(dueDate)  + "\n");
      }
      content.append("</td></tr></table>");
      content.append(sDetail+":&nbsp; <a href='"+TextUtility.formatRedirectLoginString("workflow/ListWorkflowTask.do")+"'>"+sHere+"</a>");
      progressDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public StringBuffer emailForDelegationContent(String userName, Integer delegationID) {
    StringBuffer content = new StringBuffer();

    try {
      UserDelegationDAObject delegationDAO = new UserDelegationDAObject(sessionContainer, conn);
      UserDelegation delegation = (UserDelegation)delegationDAO.getObjectByID(delegationID);

      content.append(sDear + " "+ userName + ",\n\n");
      content.append("<table border=0><tr><td>");
      content.append(sYou).append("</td><td>:</td><td>").append(UserInfoFactory.getUserFullName(delegation.getSourceUserID())+sTask);
      content.append("</td></tr>");
      content.append("<tr><td>");
      content.append(sFrom).append("</td><td></td><td>").append(TextUtility.formatTimestampToDate(delegation.getStartDate())
            +" "+getWeekdayByDate(delegation.getStartDate())+" "+sTo +" "+
                        TextUtility.formatTimestampToDate(delegation.getEndDate())
                                                +" "+getWeekdayByDate(delegation.getEndDate())+" "+sUntil);
      content.append("</td></tr></table>");
      delegationDAO=null;
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public StringBuffer emailForNotifyDelegationUserContent(String userName, Integer trackID) {
    StringBuffer content = new StringBuffer();

    try {
      content.append(sDear +" "+ userName + ",\n\n");
      String trackStr=TextUtility.formatNumberWithZeroPrefix(
          SystemParameterFactory.getSystemParameterInteger(
          SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH).intValue(),
          trackID);
      content.append(sDelegated+trackStr);
      //content.append("during the period from "+TextUtility.formatTimestampToDate(wfProgress.getStartDate())+ " to " + TextUtility.formatTimestampToDate(delegation.getEndDate()) + " until further notice.\n\n");
    } catch (Exception e) {
      log.error(e, e);
    }

    return content;
  }

  public String getWeekdayByDate(Timestamp inDate){
   String   weedayStr = "";
   if(inDate == null){
    return  weedayStr;
   }
   Calendar date = Utility.timestampToCalendar(inDate);
   String sSunday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.sun");
   String sMonday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.mon");
   String sTuesday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.tue");
   String sWednesday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.wed");
   String sThursday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.thu");
   String sFriday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.fri");
   String sSaturday = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"calendar.columnheader.sat");

   switch(date.get(Calendar.DAY_OF_WEEK)){
     case 1:
        weedayStr = sSunday;
        break;
     case 2:
        weedayStr = sMonday;
        break;
     case 3:
        weedayStr = sTuesday;
        break;
     case 4:
        weedayStr = sWednesday;
        break;
     case 5:
        weedayStr = sThursday;
        break;
     case 6:
        weedayStr = sFriday;
        break;
     case 7:
        weedayStr = sSaturday;
        break;
   }

   return "("+weedayStr+")";

  }
  protected void multiNotifyByEmailInvite(String objectType, String objectID,String eventType,MtmUpdateAlertRecipient[] updateRecipient,String objectName, Timestamp refDate,
                                         String eventName, Integer creatorID,List notifyUserIDList,boolean sendBySystem,Integer systemLogID) throws ApplicationException {

     log.debug("******** notification of email invite system : " + eventType);
     String [] documentID = TextUtility.splitString(objectID,",");
     //String [] objectTypeArray=TextUtility.splitString(objectType,",");
     UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(sessionContainer, conn);
     UpdateAlert updateAlert=new UpdateAlert();
     for (int i = 0; i < notifyUserIDList.size(); i++) {
       int notifyUserID = ( (Integer)notifyUserIDList.get(i)).intValue();
       //Disable the notification to creatror
       String sObjectName = objectName.substring(0,objectName.lastIndexOf(","));
       Integer userID = (Integer)notifyUserIDList.get(i);
       String userName = UserInfoFactory.getUserFullName(userID);
       String userEmail = this.getUserEmailAddress(userID);
       StringBuffer content = new StringBuffer();
       log.debug("******** invite recipient user ID : " + userID + " email = " + userEmail);

       if (userEmail != null && !"".equals(userEmail)) {
         try {
             updateAlert = (UpdateAlert) updateAlertDAO.getByObjectTypeObjectID(GlobalConstant.OBJECT_TYPE_DOCUMENT, TextUtility.parseIntegerObj(documentID[i]));

           if (UpdateAlert.INVITE_ACTION.equals(eventType)) {
             if (UpdateAlert.DOCUMENT_TYPE.equals(objectType)) {
                 content = emailForMultiDocumentInviteContent(objectName, objectID, eventType, userName, userID, updateAlert, eventName,systemLogID);
             }else if (UpdateAlert.CALENDAR_TYPE.equals(objectType)) {
                 content = emailForCalendarInviteContent(objectName, TextUtility.parseIntegerObj(documentID[i]),eventType, userName, refDate, eventName, creatorID);
             }
           }else if (UpdateAlert.NOTIFY_TASK_COMPLETED_ACTION.equals(eventType)) {
                 content = emailForWorkflowNotifyTaskCompletedContent(userName, userID, TextUtility.parseIntegerObj(documentID[i]));
           }else if (UpdateAlert.NOTIFY_TASK_ARRIVED_ACTION.equals(eventType)) {
                 content = emailForWorkflowNotifyTaskArrivedContent(userName, userID, TextUtility.parseIntegerObj(documentID[i]));
           }else if (UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(eventType)) {
                 content = emailForWorkflowNotifyTaskOwnerOverdueContent(userName, TextUtility.parseIntegerObj(documentID[i]));
           }else if (UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(eventType)) {
                 content = emailForWorkflowNotifyTaskAllOverdueContent(userName, TextUtility.parseIntegerObj(documentID[i]));
           }else if (UpdateAlert.NOTIFY_STOP_TRACK.equals(eventType)) {
                 content = emailForWorkflowNotifyTrackStop(userName, TextUtility.parseIntegerObj(documentID[i]));
           }else if (UpdateAlert.DELEGATION_ACTION.equals(eventType)) {
                 content = emailForDelegationContent(userName, TextUtility.parseIntegerObj(documentID[i]));
           }else if (UpdateAlert.NOTIFY_DELEGATION_USER.equals(eventType)) {
                 content = emailForNotifyDelegationUserContent(userName, TextUtility.parseIntegerObj(documentID[i]));
           }
           EmailDeliveryMessage msg = getEmailDeliveryMessage(creatorID, sendBySystem, userName, userEmail);

          if (UpdateAlert.CALENDAR_TYPE.equals(objectType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.CALENDAR_MAIL_SUBJECT));
          }else if (UpdateAlert.NOTIFY_TASK_COMPLETED_ACTION.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_MAIL_COMPLETED_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.NOTIFY_TASK_ARRIVED_ACTION.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_MAIL_ARRIVED_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_MAIL_OVERDUE_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_MAIL_OVERDUE_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.NOTIFY_STOP_TRACK.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_MAIL_TRACK_STOP_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.DELEGATION_ACTION.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_DELEGATION_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.NOTIFY_DELEGATION_USER.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.WORKFLOW_DELEGATION_USER_NOTIFICATION_SUBJECT));
          }else if (UpdateAlert.INVITE_ACTION.equals(eventType)) {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.DMS_MAIL_INVITE_SUBJECT)+" [ "+sObjectName + " ] ");
          }else if(UpdateAlert.DISCUSS_ACTION.equals(eventType)){
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.DMS_MAIL_INVITE_SUBJECT)+" [ "+sObjectName + " ] ");
          }else {
             msg.setSubject(SystemParameterFactory.getSystemParameter(
             SystemParameterConstant.DMS_MAIL_ALERT_SUBJECT)+" [ "+sObjectName + " ] ");
          }
          msg.setMailContent(content.toString());
          NotificationWay emailNotification = NotificationWayFactory.getNotificationInstance(NotificationWay.EMAIL_NOTIFICATION_INSTANCE);
          emailNotification.addDeliveryMessage( msg);
          emailNotification.send();
     }catch (UnsupportedEncodingException uee) {
        throw new ApplicationException("UnspportedEncodingException");
     }
   }

  }
 }
  public StringBuffer emailForMultiDocumentInviteContent(String objectName, String objectID, String eventType, String userName, Integer userID, UpdateAlert updateAlert, String eventName,Integer systemLogID) throws ApplicationException{
    StringBuffer content = new StringBuffer();
    String dueDate = "";
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(sessionContainer, conn);
    String fieldValue="";
    String hostName = UserInfoFactory.getUserFullName(updateAlert.getCreatorID());
    String [] documentID = TextUtility.splitString(objectID,",");
    UpdateAlertType alertType = new UpdateAlertType();
    UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(sessionContainer, conn);

    content.append(sDear + " "+ userName + ",\n\n");
    sNotify=MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"alert.message.notify",hostName);
    content.append(sNotify+ "\n\n");
    for(int i=0;i<documentID.length;i++){
     List alertTypeList = updateAlertTypeDAO.getByUpdateAlertIDByOwnerID(updateAlert.getID(), UpdateAlert.INVITE_ACTION, sessionContainer.getUserRecordID());
     if (!Utility.isEmpty(alertTypeList)) {
        alertType = (UpdateAlertType) alertTypeList.get(0);
        dueDate = TextUtility.formatTimestampToDate(alertType.getDueDate());
      }
    DmsDocument dmsDocument = docRetrievalManager.getDocument(TextUtility.parseIntegerObj(documentID[i]));
    if (dmsDocument!=null) {
      String location = docRetrievalManager.getLocationPath(dmsDocument.getParentID());
      String sCurFunctionCode = docRetrievalManager.getCurFunctionCode(dmsDocument);
      String appBaseURL = getApplicationBaseURL();
//      String onClickURL=appBaseURL + "/dms/MaintDmsDocument.do?documentType=" + dmsDocument.getDocumentType() + "&rootID=" + dmsDocument.getRootID() + "&parentID="
//      + dmsDocument.getID() + "&sCurFunctionCode=" + sCurFunctionCode + "&navMode=" + GlobalConstant.NAV_MODE_PREVIEW + "&ID=" + dmsDocument.getID() + "&objectID=" + dmsDocument.getID()+"&fromEmail=true";
//      if(systemLogID!=null){
//        onClickURL = onClickURL + "&updateAlertSystemLogID="+systemLogID+"&updateReadOperation="+"true";
//      }
      //Add By Jim Zhou   2006/10/18    EIP-378
      UpdateAlert updateAlertTemp = (UpdateAlert) updateAlertDAO.getByObjectTypeObjectID(GlobalConstant.OBJECT_TYPE_DOCUMENT, TextUtility.parseIntegerObj(documentID[i]));
      //Add End
      //Update By Jim Zhou      2006/10/18    EIP-378
      String onClickURL=appBaseURL + "/dms/ViewInvitation.do?updateAlertID="+updateAlertTemp.getID()+ "&objectID=" + dmsDocument.getID();

      String referenceNo = dmsDocument.getReferenceNo();
      String description = dmsDocument.getDescription();
      Timestamp effectiveDate = dmsDocument.getEffectiveStartDate();
      SysUserDefinedIndex udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(dmsDocument);
      SysUserDefinedIndexDetail udfDetail=null;
//      try {
//        onClickURL = "'" + appBaseURL + "/Login.do?action=redirect&userID="+userID+"&url="+java.net.URLEncoder.encode(onClickURL, "UTF-8") +"' ";
//      } catch (java.io.UnsupportedEncodingException e) {
//        throw new ApplicationException(e);
//      }
      content.append("\n\n");
      content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.location") + ": " + location + "\n");
      content.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_" + dmsDocument.getDocumentType()) + ": ");
      content.append("<a href='" + onClickURL + "' target='DCIVisionAppWindow'>" + dmsDocument.getDocumentName() + "</a>\n");
      content.append(sReferenceNo +": "+referenceNo + "\n");
      content.append(sDescription +": "+description + "\n");
      if (udfIndex!=null) {
        content.append(sProfileName+": "+udfIndex.getUserDefinedType()+"\n");
        List udfDetailList = docRetrievalManager.getUDFDetailList(udfIndex.getID());
        for (int k=0; k<udfDetailList.size(); k++) {
          udfDetail = (SysUserDefinedIndexDetail)udfDetailList.get(k);
          DmsDocumentDetail dmsDocumentDetail = docRetrievalManager.getDetailObjectByDocIDUDFDetailID(dmsDocument.getID(), udfDetail.getID());

          if (dmsDocumentDetail!=null){
            if (udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.DATE_FIELD) ){
              fieldValue = dmsDocumentDetail.getDateValue()==null ? "" : dmsDocumentDetail.getDateValue().toString();
            } else if (udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.STRING_FIELD) ||
                       udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.FIELD_TYPE_SELECT_DATABASE)){
              fieldValue = dmsDocumentDetail.getFieldValue()==null ? "" : dmsDocumentDetail.getFieldValue().toString();
            } else if (udfDetail.getFieldType().equals(SysUserDefinedIndexDetail.NUMBER_FIELD) ){
              fieldValue = dmsDocumentDetail.getNumericValue()==null? "" : dmsDocumentDetail.getNumericValue().toString();
            }
          }
          content.append(udfDetail.getFieldName()+": "+fieldValue+"\n");
        }

      }
      content.append(sEffectiveDate +": "+TextUtility.formatDate(effectiveDate,SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATETIME_FORMAT))+"\n");
    }


      if(!Utility.isEmpty(dueDate)){
        content.append(sDuteDate +" "+ dueDate+" "+ getWeekdayByDate(alertType.getDueDate())  + "\n");
      }
    }
    String message=alertType.getMessage()==null ?"":alertType.getMessage().toString();
    content.append("\n\n");
    content.append(sMessage +" "+ message + "\n");
    content.append(sHostName +": "+hostName + "\n");
    content.append("\n\n");
    docRetrievalManager.release();
    return content;
  }

  protected String getApplicationBaseURL(){
  return SystemParameterFactory.getSystemParameter(SystemParameterConstant.APPLICATION_BASE_URL);
  }

  protected String[] getUserDefaultProfiles(DmsDocument dmsDocument) throws ApplicationException {
    String[] profiles = new String[10];
    profiles[0] = dmsDocument.getUserDef1();
    profiles[1] = dmsDocument.getUserDef2();
    profiles[2] = dmsDocument.getUserDef3();
    profiles[3] = dmsDocument.getUserDef4();
    profiles[4] = dmsDocument.getUserDef5();
    profiles[5] = dmsDocument.getUserDef6();
    profiles[6] = dmsDocument.getUserDef7();
    profiles[7] = dmsDocument.getUserDef8();
    profiles[8] = dmsDocument.getUserDef9();
    profiles[9] = dmsDocument.getUserDef10();

    String sysParamCount = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT);
    int counter = sysParamCount!=null ? Integer.parseInt(sysParamCount) : 0;
    String[] userDefaultProfiles = new String[counter];
    for (int i=0; i<counter; i++) {
      userDefaultProfiles[i] = profiles[i];
    }

    return userDefaultProfiles;
  }

  //for email address changed ,can not get from sessionContainer.
  protected String getUserEmailAddress(Integer userRecordID) throws ApplicationException {
    UserRecordDAObject userRecordDAO = new UserRecordDAObject(sessionContainer,conn);
    String emailAddress = "";
    if(!Utility.isEmpty(userRecordID)){
      UserRecord userRecord = (UserRecord)userRecordDAO.getObjectByID(userRecordID);
      if(!Utility.isEmpty(userRecord)){
        emailAddress = userRecord.getEmail();
      }
    }
    return emailAddress;
  }
}